#include "XmlUtil.h"

CXmlUtil::CXmlUtil()
{
	m_xmlParse = new tinyxml2::XMLDocument();
}

CXmlUtil::~CXmlUtil()
{
	if (m_xmlParse) {
		delete m_xmlParse;
		m_xmlParse = 0;
	}
}

void CXmlUtil::xParseFunc(tinyxml2::XMLElement* hItem, std::string text, bool bRepeat)
{
	tinyxml2::XMLElement* hChildItem = 0;
	if (NULL == hItem) {
		return;
	}

	if (bRepeat) {
		text += hItem->Name();
	}

	const tinyxml2::XMLAttribute* hAtt = hItem->FirstAttribute();
	if (NULL != hAtt) {
		m_MapField[hItem->Name()] = hAtt->Value();
		bRepeat = true;
	}

	if (hItem->GetText()) {
		if (bRepeat) {
			int  i = 0;
			char temp[64] = { 0 };
			sprintf(temp, "%s%d", text.c_str(), i++);
			while (m_MapField.find(temp) != m_MapField.end()) {
				sprintf(temp, "%s%d", text.c_str(), i++);
			}
			m_MapField[temp] = hItem->GetText();
		}
		else {
			m_MapField[hItem->Name()] = hItem->GetText();
		}
	}

	hChildItem = hItem->FirstChildElement();
	if (NULL == hChildItem) {
		return;
	}

	xParseFunc(hChildItem, text, bRepeat);

	hChildItem = hChildItem->NextSiblingElement();
	while (hChildItem) {

		xParseFunc(hChildItem, text, bRepeat);
		hChildItem = hChildItem->NextSiblingElement();
	}
}

int CXmlUtil::ParseXml(const char* xml)
{
	if (NULL == xml)
	{
		return tinyxml2::XML_ERROR_EMPTY_DOCUMENT;
	}

	if (tinyxml2::XML_SUCCESS == m_xmlParse->Parse(xml)) {

		m_MapField.clear();

		xParseFunc(m_xmlParse->RootElement(), "", false);

		return tinyxml2::XML_SUCCESS;
	}
	return tinyxml2::XML_ERROR_PARSING;
}

int CXmlUtil::ParseFile(const char* FilePath)
{
	if (NULL == FilePath) {
		return tinyxml2::XML_ERROR_EMPTY_DOCUMENT;
	}

	FILE* pFile = fopen(FilePath, "rb");
	if (NULL != pFile) {
		char xml[4096] = { 0 };
		fread(xml, 4096, 1, pFile);
		fclose(pFile);

		m_xmlParse->Clear();

		if (tinyxml2::XML_SUCCESS == m_xmlParse->Parse(xml)) {

			m_MapField.clear();

			xParseFunc(m_xmlParse->RootElement(), "", false);

			return tinyxml2::XML_SUCCESS;
		}
	}

	return tinyxml2::XML_ERROR_PARSING;
}

int Char2Int(const std::string& mchar)
{
	int val = 0;
	int l = mchar.size();
	const char* p = mchar.c_str();

	int s = 1;

	while (isspace(*p++)) {
		l--;
	}
	p--;

	if (*p == '-')
	{
		s = -1;
		p++;
		l--;
	}

	while (l--)
	{
		char c = *p++;
		if ((c >= '0') && (c <= '9'))
		{
			val *= 10;
			val += c - '0';
		}
		else
		{
			return s * val;
		}
	}
	return s * val;
}

int CXmlUtil::GetAllChannels()
{
	return GetFieldInt("SumNum");
}

int CXmlUtil::GetNumChannel()
{
	return GetFieldInt("DeviceList");
}

int CXmlUtil::GetFieldInt(const char* fieldName) const
{
	std::map<std::string, std::string>::const_iterator Iter;
	Iter = m_MapField.find(fieldName);
	if (Iter != m_MapField.end()) {
		return Char2Int(Iter->second);
	}
	return 0;
}

int CXmlUtil::find(const char* key, const char* val) const
{
	const char*pKey = GetFieldString(key);
	if (NULL == pKey) { return -1; }
	if (0 != strcmp(pKey, val)) {
		return -1;
	}
	return 0;
}

const char* CXmlUtil::GetFieldString(const char* fieldName) const
{
	std::map<std::string, std::string>::const_iterator Iter;
	Iter = m_MapField.find(fieldName);
	if (Iter != m_MapField.end()) {
		return Iter->second.c_str();
	}
	return NULL;
}

int CXmlUtil::GetFieldValue(const char* fieldName, char* fieldvalue) const
{
	std::map<std::string, std::string>::const_iterator Iter;
	Iter = m_MapField.find(fieldName);
	if (Iter != m_MapField.end()) {
		strcpy(fieldvalue,
		Iter->second.c_str());
		return 0;
	}
	return -1;
}